Test Failed
Push — master ( 5878a7...1a655d )
by Alexey
05:08
created

Ui.js ➔ CustomSelect   A

Complexity

Conditions 1
Paths 2

Size

Total Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 2
nop 0
dl 0
loc 71
rs 9.1369
c 0
b 0
f 0

3 Functions

Rating   Name   Duplication   Size   Complexity  
A Ui.js ➔ ... ➔ $(ꞌbodyꞌ).click.closeCustomSelect 0 10 2
A Ui.js ➔ ... ➔ this.fn 0 52 2
A Ui.js ➔ ... ➔ this.bind 0 6 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/**
2
 * Main Ui object
3
 *
4
 * @returns {Ui}
5
 */
6
inji.Ui = new function () {
7
  inji.onLoad(function () {
8
    inji.Ui.bindMenu($('.nav-list-categorys'));
9
    inji.Ui.modals = new Modals();
10
    inji.Ui.forms = new Forms();
11
    inji.Ui.editors = new Editors();
12
    inji.Ui.autocomplete = new Autocomplete();
13
14
  });
15
  this.customSelect = new CustomSelect();
16
  this.bindMenu = function (container) {
17
    container.find('.nav-left-ml').toggle();
18
    container.find('label.nav-toggle span').click(function () {
19
      $(this).parent().parent().children('ul.nav-left-ml').toggle(300);
20
      var cs = $(this).attr("class");
21
      if (cs == 'nav-toggle-icon glyphicon glyphicon-chevron-right') {
22
        $(this).removeClass('glyphicon-chevron-right').addClass('glyphicon-chevron-down');
23
      }
24
      if (cs == 'nav-toggle-icon glyphicon glyphicon-chevron-down') {
25
        $(this).removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-right');
26
      }
27
    });
28
  };
29
  this.requestInfo = function (options, callback) {
30
    var id = 'resultForm' + inji.randomString();
31
    var body = '<form id ="' + id + '">';
32
    body += '<h2>' + options.header + '</h2>';
33
    for (var key in options.inputs) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
34
      body += '<div class = "form-group">';
35
      body += '<label>' + options.inputs[key].label + '</label>';
36
      body += '<input type = "' + options.inputs[key].type + '" name = "' + key + '" class ="form-control" />';
37
      body += '</div>';
38
    }
39
    body += '<button class = "btn btn-primary">' + options.btn + '</button>';
40
    body += '</form>';
41
    var modal = inji.Ui.modals.show('', body);
42
    $('#' + id).on('submit', function () {
43
      callback($('#' + id).serializeArray());
44
      modal.modal('hide');
45
      return false;
46
    });
47
  }
48
};
49
50
function CustomSelect() {
51
  this.bind = function (jqueryEl) {
52
    var self = this;
53
    jqueryEl.each(function () {
54
      new self.fn($(this));
0 ignored issues
show
Unused Code Best Practice introduced by
The object created with new self.fn($(this)) is not used but discarded. Consider invoking another function instead of a constructor if you are doing this purely for side effects.
Loading history...
55
    });
56
  };
57
  this.fn = function (jqueryEl) {
58
    jqueryEl[0].__inji_customSelect__ = this;
59
    var self = this;
60
    this.select = jqueryEl.find('select');
61
    var htmlOptions = this.select.html();
62
    htmlOptions = htmlOptions.replace(/option/g, 'div');
63
    console.log(htmlOptions);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
64
    this.custom = $('<div class="customSelect">\
65
                                        <div class="main-box">\
66
                                            <div class="current-item"></div>\
67
                                            <div class="chevron"><div><i class="glyphicon glyphicon-chevron-down"></i></div><div style="display:none;"><i class="glyphicon glyphicon-chevron-up"></i></div></div>\
68
                                        </div>\
69
                                        <div class="item-list">\
70
                                        ' + htmlOptions + '\
71
                                        </div>\
72
                                    </div>');
73
74
    this.custom.find('.item-list>*').addClass('list-item');
75
    this.custom.find('.main-box').click(function (e) {
76
      var element = $(this).next()[0];
77
      $('.customSelect .item-list').each(function () {
78
        if (element != this && $(this).css('display') == 'block') {
79
          $(this).slideUp();
80
          $(this).closest('.customSelect').find('.chevron>*').slideToggle();
81
        }
82
      });
83
      self.toggle();
84
    });
85
    jqueryEl.prepend(this.custom);
86
    var text = this.select.find("option:selected").html();
87
    this.custom.find('.current-item').html(text);
88
    this.select.change(function () {
89
      var text = self.select.find("option:selected").html();
90
      self.custom.find('.current-item').html(text);
91
    });
92
    this.custom.find('.list-item').click(function () {
93
      self.select.find('option:selected')[0].selected = false;
94
      self.select.find('option').get($(this).index()).selected = true;
95
      self.select.change();
96
      self.toggle();
97
    });
98
    if (this.select.find(':selected').val() != 0) {
99
      $(this.custom.find('.list-item')[$(this).find(':selected').val()]).click();
100
      $(this).change();
101
    }
102
    this.toggle = function () {
103
      console.log('toggle');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
104
      self.custom.find('.item-list').slideToggle();
105
      self.custom.find('.chevron>*').slideToggle();
106
    };
107
108
  };
109
  $('body').off('click.closeCustomSelect');
110
  $('body').on('click.closeCustomSelect', function (e) {
111
    if ($(e.target).closest('.customSelect').length == 0) {
112
      $('.customSelect .item-list').each(function () {
113
        if ($(this).css('display') == 'block') {
114
          $(this).slideUp();
115
          $(this).closest('.customSelect').find('.chevron>*').slideToggle();
116
        }
117
      });
118
    }
119
  });
120
}
121
122
function Autocomplete() {
123
  this.autocompletes = [];
124
  this.bind = function (element, options, params) {
125
    var autocomplete = new this.fn(element, options, params);
126
    element.element.__inji_autocomplete = autocomplete;
127
    this.autocompletes.push(autocomplete);
128
  };
129
  this.fn = function (element, snippet, snippetParams) {
130
    this.element = element;
131
    this.snippet = snippet;
132
    this.snippetParams = snippetParams;
133
    this.reqestProcess = null;
134
    this.inputContainer = element.element.parentNode;
135
    this.selectedDiv = this.inputContainer.querySelector('.form-search-cur');
136
    this.resultsDiv = this.inputContainer.querySelector('.form-search-results');
137
    this.changer = this.inputContainer.querySelector('.custominput-clear');
138
    this.hidden = this.inputContainer.querySelector('[type="hidden"]');
139
140
    var self = this;
141
    this.element.element.onkeyup = function () {
142
      self.loadResult(this.value);
143
    };
144
145
    this.clear = function () {
146
      this.setValue('', '')
147
    };
148
    this.setValue = function (value, text) {
149
      this.hidden.value = value;
150
      if (this.hidden.fireEvent !== undefined)
151
        this.hidden.fireEvent("onchange");
152
      else {
153
        var evt = document.createEvent("HTMLEvents");
154
        evt.initEvent("change", false, true);
155
        this.hidden.dispatchEvent(evt);
156
      }
157
      this.inputContainer.querySelector('[type="text"]').value = text;
158
      this.selectedDiv.innerHTML = 'Выбрано: ' + text;
159
      this.resultsDiv.style.display = 'none';
160
      this.changer.style.display = value ? 'block' : 'none';
161
    };
162
    this.loadResult = function (search) {
163
      if (this.reqestProcess) {
164
        this.reqestProcess.abort()
165
      }
166
      this.resultsDiv.innerHTML = '<div class = "text-center"><img src = "' + inji.options.appRoot + 'static/moduleAsset/Ui/images/ajax-loader.gif" /></div>';
167
      this.resultsDiv.style.display = 'block';
168
      this.reqestProcess = inji.Server.request({
169
        url: 'ui/autocomplete',
170
        data: {
171
          snippet: this.snippet,
172
          snippetParams: this.snippetParams,
173
          search: search
174
        },
175
        success: function (results) {
176
          self.resultsDiv.innerHTML = '';
177
          for (var key in results) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
178
            var result = results[key];
179
            var resultElement = document.createElement("div");
180
            resultElement.setAttribute('objectid', key);
181
            resultElement.appendChild(document.createTextNode(result));
182
            resultElement.onclick = function () {
183
              var value = 0;
184
              for (var key2 in this.attributes) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
185
                if (this.attributes[key2].name === 'objectid') {
186
                  value = this.attributes[key2].value;
187
                }
188
              }
189
              self.setValue(value, this.innerText);
190
            };
191
            self.resultsDiv.appendChild(resultElement);
192
          }
193
          self.resultsDiv.style.display = 'block';
194
        }
195
      });
196
    };
197
198
  };
199
}
200
201
/**
202
 * Editors
203
 *
204
 */
205
var Editors = function () {
206
  this.ckeditor = false;
207
  this.checkEditors();
208
  inji.on('loadScript', function () {
209
    inji.Ui.editors.checkEditors();
210
  });
211
  inji.onLoad(function () {
212
    inji.Ui.editors.loadIn('.htmleditor');
213
  })
214
};
215
Editors.prototype.checkEditors = function () {
216
  if (!this.ckeditor && typeof CKEDITOR != 'undefined') {
217
    this.ckeditor = true;
218
  }
219
};
220
Editors.prototype.loadAll = function () {
221
222
};
223
Editors.prototype.loadIn = function (selector, search) {
224
  if (this.ckeditor) {
225
    setTimeout(function () {
226
      var instances;
227
      if (typeof search != 'undefined') {
228
        instances = $(selector).find(search);
229
      } else {
230
        instances = $(selector);
231
      }
232
      $.each(instances, function () {
233
        var editor;
234
        var _this = this;
235
        if ($(this).closest('.modal').length == 0 || $(this).closest('.modal').hasClass('in')) {
236
          editor = $(_this).ckeditor({customConfig: inji.options.appRoot + 'static/moduleAsset/libs/libs/ckeditor/program/userConfig.php'});
237
        }
238
        if ($(this).closest('.modal').length != 0) {
239
          $(this).closest('.modal').on('shown.bs.modal', function () {
240
            setTimeout(function () {
241
              editor = $(_this).ckeditor({customConfig: inji.options.appRoot + 'static/moduleAsset/libs/libs/ckeditor/program/userConfig.php'});
242
            }, 1000);
243
          });
244
          $(this).closest('.modal').on('hide.bs.modal', function () {
245
            if (editor.editor) {
0 ignored issues
show
Bug introduced by
The variable editor does not seem to be initialized in case $(this).closest(".modal"....modal").hasClass("in") on line 235 is false. Are you sure this can never be the case?
Loading history...
246
              editor.editor.updateElement();
247
              editor.editor.destroy();
248
              delete editor.editor;
249
              $(this).closest('.modal').unbind('hide.bs.modal');
250
              $(this).closest('.modal').unbind('shown.bs.modal');
251
            }
252
253
          })
254
        }
255
      })
256
    }, 1000);
257
  }
258
};
259
Editors.prototype.beforeSubmit = function (form) {
260
  if (this.ckeditor) {
261
    $.each(CKEDITOR.instances, function () {
262
      this.updateElement();
263
    });
264
    $.each($(form).find('.cke'), function () {
265
      var instance = $(this).attr('id').replace('cke_', '');
266
      $(CKEDITOR.instances[instance].element).closest('.modal').unbind();
267
      CKEDITOR.instances[instance].destroy();
268
    });
269
  }
270
};
271
/**
272
 * Modals objects
273
 *
274
 * @returns {Modals}
275
 */
276
var Modals = function () {
277
  this.modals = 0;
278
};
279
Modals.prototype.show = function (title, body, code, size) {
280
  if (code == null) {
281
    code = 'modal' + (++this.modals);
282
  }
283
  if ($('#' + code).length == 0) {
284
    if (size == null) {
285
      size = '';
286
    }
287
    if (title) {
288
      title = '<div class="modal-header">\
289
                  <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>\
290
                  <h4 class="modal-title">' + title + '</h4>\
291
                </div>';
292
    } else {
293
      title = '';
294
    }
295
    var html = '\
296
          <div class="modal fade" id = "' + code + '" >\
297
            <div class="modal-dialog ' + size + '">\
298
              <div class="modal-content">\
299
                ' + title + '\
300
                <div class="modal-body">\
301
                ' + body + '\
302
                </div>\
303
                <div class="modal-footer">\
304
                  <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>\
305
                </div>\
306
              </div>\
307
            </div>\
308
          </div>';
309
    $('body').append(html);
310
311
  }
312
  var modal = $('#' + code);
313
  $('body').append(modal);
314
  modal.modal('show');
315
  return modal;
316
};
317
318
/**
319
 * Forms object
320
 *
321
 * @returns {Forms}
322
 */
323
function Forms() {
324
  this.dataManagers = 0;
325
  this.formCallbacks = {};
326
}
327
328
Forms.prototype.popUp = function (item, params, callback) {
329
  var code = item;
330
331
  if (typeof params == 'undefined') {
332
    params = {};
333
  }
334
  if (typeof (params.relation) != 'undefined') {
335
    code += params.relation;
336
  }
337
  code = code.replace(/:/g, '_').replace(/\\/g, '_');
338
  var modal = inji.Ui.modals.show('', '<div class = "text-center"><img src = "' + inji.options.appRoot + 'static/moduleAsset/Ui/images/ajax-loader.gif" /></div>', code, 'modal-lg');
339
  inji.Server.request({
340
    url: 'ui/formPopUp/',
341
    data: {item: item, params: params},
342
    success: function (data) {
343
      modal.find('.modal-body').html(data);
344
      if (callback) {
345
        inji.Ui.forms.formCallbacks[modal.find('.form').attr('id')] = callback;
346
      }
347
      inji.Ui.editors.loadIn(modal.find('.modal-body'), '.htmleditor');
348
    }
349
  });
350
};
351
Forms.prototype.submitAjax = function (form, params) {
352
  inji.Ui.editors.beforeSubmit(form);
353
  var form = $(form);
354
  var container = form.parent().parent();
355
  var btn = form.find('button');
356
  btn.text('Подождите');
357
  btn[0].disabled = true;
358
  btn.data('loading-text', "Подождите");
359
360
  var url = form.attr('action');
361
  if (params) {
362
    var first = true;
363
    if (url.indexOf('?') >= 0) {
364
      first = false;
365
    }
366
    for (var key in params) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
367
      url += (first ? '?' : '&') + key + '=' + params[key];
368
    }
369
  }
370
  var formData = new FormData(form[0]);
371
  inji.Server.request({
372
    url: url,
373
    type: 'POST',
374
    data: formData,
375
    processData: false,
376
    success: function (data) {
377
      if (inji.Ui.forms.formCallbacks[form.attr('id')]) {
378
        inji.Ui.forms.formCallbacks[form.attr('id')]();
379
        delete inji.Ui.forms.formCallbacks[form.attr('id')];
380
      }
381
      container.html(data);
382
      inji.Ui.editors.loadIn(container, '.htmleditor');
383
      inji.Ui.dataManagers.reloadAll();
384
      if (params && !params.notSave) {
385
        var btn = container.find('form button');
386
        var text = btn.text();
387
        btn.text('Изменения сохранены!');
388
        setTimeout(function () {
389
          btn.text(text)
390
        }, 3000);
391
      }
392
    }
393
  });
394
};
395
Forms.prototype.addRowToList = function (btn) {
396
  var container = $(btn).closest('.dynamicList');
397
  var counter = parseInt(container.find('.sourceRow').data('counter')) + 1;
398
  container.find('.sourceRow').data('counter', counter);
399
  var trHtml = container.find('.sourceRow script').html().replace(/^\/\*/g, '').replace(/\*\/$/g, '').replace(/\[counterPlaceholder\]/g, '[' + counter + ']');
400
  container.find('.listBody').append(trHtml);
401
};
402
Forms.prototype.checkAditionals = function (select) {
403
  var selectedInputAd = $(select).find('option:selected').attr('data-aditionalInput');
404
  var nextSelect = $(select).next();
405
  var i = 0;
406
  if ($(select).data('aditionalEnabled') == 1) {
407
    $(select).data('aditionalEnabled', 0);
408
  }
409
  while (nextSelect.length) {
410
    if (i != selectedInputAd) {
411
      nextSelect[0].disabled = true;
412
      nextSelect.addClass('hidden');
413
    } else {
414
      if ($(select).data('aditionalEnabled') != 1) {
415
        $(select).data('aditionalEnabled', 1);
416
      }
417
      nextSelect[0].disabled = false;
418
      nextSelect.removeClass('hidden');
419
    }
420
    nextSelect = $(nextSelect).next();
421
    i++;
422
  }
423
};
424
Forms.prototype.delRowFromList = function (btn) {
425
  $(btn).closest('tr').remove();
426
};
427
428
inji.Ui.activeForms = new function () {
429
  this.activeForms = [];
430
  this.get = function (selector) {
431
    var element = inji.get(selector);
432
    if (element && element.data('activeFormIndex') !== null) {
433
      return this.activeForms[element.data('activeFormIndex')];
434
    }
435
    this.initial(element);
436
  };
437
  this.initial = function (element) {
438
    var activeForm = new ActiveForm();
439
    this.activeForms.push(activeForm);
440
441
    activeForm.index = this.activeForms.length - 1;
442
    activeForm.element = element;
443
    activeForm.modelName = element.data('modelname');
444
    activeForm.formName = element.data('formname');
445
    activeForm.inputs = element.data('inputs');
446
447
    element.element.setAttribute('activeFormIndex', activeForm.index);
448
449
    activeForm.load();
450
  }
451
};
452
453
function ActiveForm() {
454
  this.modelName;
0 ignored issues
show
introduced by
The result of the property access to this.modelName is not used.
Loading history...
455
  this.formName;
0 ignored issues
show
introduced by
The result of the property access to this.formName is not used.
Loading history...
456
  this.reqestProcess;
0 ignored issues
show
introduced by
The result of the property access to this.reqestProcess is not used.
Loading history...
457
  this.inputs = {};
458
  this.index;
0 ignored issues
show
introduced by
The result of the property access to this.index is not used.
Loading history...
459
  this.element;
0 ignored issues
show
introduced by
The result of the property access to this.element is not used.
Loading history...
460
  this.load = function () {
461
    for (var inputName in this.inputs) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
462
      var inputParams = this.inputs[inputName];
463
      var self = this;
464
      if (this.inputHandlers[inputParams.type]) {
465
        var query = '#' + this.element.element.id + ' [name="query-ActiveForm_' + this.formName + '[' + this.modelName.replace(/\\/g, '\\\\') + '][' + inputName + ']"]';
466
        this.inputHandlers[inputParams.type](inji.get(query), inputName, this);
467
      }
468
      if (inputParams.onChange == 'reloadForm') {
469
        var query = '#' + this.element.element.id + ' [name="ActiveForm_' + this.formName + '[' + this.modelName.replace(/\\/g, '\\\\') + '][' + inputName + ']"]';
470
        $(query).on('change', function () {
471
          inji.Ui.forms.submitAjax($('#' + self.element.element.id + ' form')[0], {notSave: true});
0 ignored issues
show
Bug introduced by
The variable self is changed as part of the for-each loop for example by this on line 463. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
472
        })
473
      }
474
    }
475
  };
476
  this.inputHandlers = {
477
    search: function (element, inputName, activeForm) {
478
      element.element.onkeyup = function () {
479
        var inputContainer = element.element.parentNode;
480
        var selectedDiv = inputContainer.querySelector('.form-search-cur');
481
        var resultsDiv = inputContainer.querySelector('.form-search-results');
482
        resultsDiv.innerHTML = '<div class = "text-center"><img src = "' + inji.options.appRoot + 'static/moduleAsset/Ui/images/ajax-loader.gif" /></div>';
483
        if (this.reqestProcess) {
484
          this.reqestProcess.abort()
485
        }
486
        this.reqestProcess = inji.Server.request({
487
          url: 'ui/activeForm/search',
488
          data: {
489
            modelName: activeForm.modelName,
490
            formName: activeForm.formName,
491
            inputName: inputName,
492
            search: this.value
493
          },
494
          success: function (results) {
495
            resultsDiv.innerHTML = '';
496
            for (var key in results) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
497
              var result = results[key];
498
              var resultElement = document.createElement("div");
499
              resultElement.setAttribute('objectid', key);
500
              resultElement.appendChild(document.createTextNode(result));
501
              resultElement.onclick = function () {
502
                var value = 0;
503
                for (key in this.attributes) {
504
                  if (this.attributes[key].name == 'objectid') {
0 ignored issues
show
introduced by
The variable key is changed by the for-each loop on line 503. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
505
                    value = this.attributes[key].value;
506
                  }
507
                }
508
                inputContainer.querySelector('[type="hidden"]').value = value;
509
                inputContainer.querySelector('[type="text"]').value = this.innerHTML;
510
                selectedDiv.innerHTML = 'Выбрано: ' + this.innerHTML;
511
                resultsDiv.innerHTML = '';
512
              };
513
              resultsDiv.appendChild(resultElement);
514
            }
515
            resultsDiv.style.display = 'block';
516
          }
517
        })
518
      };
519
    }
520
  };
521
}